/**
 * 
 */
package com.test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.apache.poi.xwpf.usermodel.IRunBody;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.poi.xwpf.usermodel.XWPFRun;
import org.ehcache.core.util.CollectionUtil;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTRunTrackChange;
import org.springframework.util.CollectionUtils;

/**
 * @Description TODO(这里用一句话描述这个类的作用)
 *
 * @author liuqinghua
 * @Date 2025-7-1
 */
public class WordTest3 {
    public static void main(String[] args) throws FileNotFoundException, IOException {

        List<CommontDto> fixList = new ArrayList<CommontDto>();
        CommontDto f1 = new CommontDto();
        f1.setOriginal("外国游客");
        f1.setSuggestion("国际友人");
        fixList.add(f1);
//        CommontDto f2 = new CommontDto();
//        f2.setOriginal("自中国");
//        f2.setSuggestion("自东方大国");
//        fixList.add(f2);
//
//        CommontDto f3 = new CommontDto();
//        f3.setOriginal("要和大家说：");
//        f3.setSuggestion("通知：");
//        fixList.add(f3);

        XWPFDocument document = new XWPFDocument(new FileInputStream(new File("d:/opt/test2.docx")));

        List<XWPFParagraph> paragraphs = document.getParagraphs();

        for (XWPFParagraph paragraph : paragraphs) {
            String graphText = paragraph.getText();
            for (CommontDto pz : fixList) {
                String source = pz.getOriginal();
                String target = pz.getSuggestion();
                int matchTimes = 0;
                boolean next = false;
                while (!next && matchTimes < 10 && graphText.contains(source)) {
                    // 同一段，同一个修改项，最多匹配10次，防止死循环
                    matchTimes++;
                    int matchRunIndex = -1;
                    List<XWPFRun> runs = paragraph.getRuns();
                    int sourceRunSize = runs.size();
                    List<Integer> removeList = new ArrayList<Integer>();
                    for (int i = 0; i < runs.size(); i++) {
                        XWPFRun run = runs.get(i);
                        String runText = run.toString();
                        if (runText.contains(source)) {
                            matchRunIndex = i;
                            break;
                        }
                    }
                    if (matchRunIndex > -1) {
                        XWPFRun run = runs.get(matchRunIndex);
                        String runText = run.toString();
                        int index = runText.indexOf(source);
                        run.setText(runText.substring(0, index), 0);
                        addDeletedText(paragraph, source, "系统", Calendar.getInstance(), run);
                        addInsertedText(paragraph, target, "系统", Calendar.getInstance(), run);

                        if (!runText.equals(source)) {
                            XWPFRun suffixRun = paragraph.createRun();
                            suffixRun.setFontFamily(run.getFontFamily());
                            suffixRun.setBold(run.isBold());
                            suffixRun.setFontSize(run.getFontSizeAsDouble());
                            suffixRun.setColor(run.getColor());
                            String text = runText.substring(index + source.length());
                            suffixRun.setText(text);
                        }
                        // 修订内容插入在段落最后，所以要把匹配到的run后面的run移动到修订内容后面
                        for (int i = matchRunIndex + 1; i < sourceRunSize; i++) {
                            removeList.add(i);
                            XWPFRun curr = runs.get(i);
                            XWPFRun runCopy = paragraph.createRun();
                            runCopy.setFontFamily(curr.getFontFamily());
                            runCopy.setBold(curr.isBold());
                            runCopy.setFontSize(curr.getFontSizeAsDouble());
                            runCopy.setText(curr.toString());
                            runCopy.setColor(curr.getColor());
                        }
                        if (!CollectionUtils.isEmpty(removeList)) {
                            int first = removeList.get(0);
                            for (int i = 0; i < removeList.size(); i++) {
                                paragraph.removeRun(first);
                            }
                        }
                    } else {
                        // 未匹配到，则开始匹配下一下修改项
                        next = true;
                    }
                    graphText = paragraph.getText();
                    runs = paragraph.getRuns();
                }
            }
        }

        try (FileOutputStream out = new FileOutputStream("d:/opt/test3.docx")) {
            document.write(out);
        }
//        document.close();
    }

    // 添加删除的文本
    private static XWPFRun addDeletedText(XWPFParagraph paragraph, String text, String author, Calendar date,
            XWPFRun sourceRun) {
        CTRunTrackChange trackChange = paragraph.getCTP().addNewDel();
        trackChange.setAuthor(author);
        trackChange.setDate(date);
        trackChange.addNewR();

        XWPFRun run = new XWPFRun(trackChange.getRArray(0), (IRunBody) paragraph);
        run.setFontSize(sourceRun.getFontSizeAsDouble());
        run.setFontFamily(sourceRun.getFontFamily());
        run.setBold(sourceRun.isBold());
        run.setColor(sourceRun.getColor());
        run.getCTR().addNewDelText().setStringValue(text);
        return run;
    }

    // 添加插入的文本（基于原始示例）
    private static XWPFRun addInsertedText(XWPFParagraph paragraph, String text, String author, Calendar date,
            XWPFRun sourceRun) {
        CTRunTrackChange trackChange = paragraph.getCTP().addNewIns();
        trackChange.setAuthor(author);
        trackChange.setDate(date);
        trackChange.addNewR();

        XWPFRun run = new XWPFRun(trackChange.getRArray(0), (IRunBody) paragraph);
        run.setFontSize(sourceRun.getFontSizeAsDouble());
        run.setFontFamily(sourceRun.getFontFamily());
        run.setBold(sourceRun.isBold());
        run.setColor(sourceRun.getColor());
        run.setText(text);
        return run;
    }

}
